﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using ClientOverflow.ViewModels.Interfaces;

namespace ClientOverflow.ViewModels.Login
{
    /// <summary>
    /// LoginViewModel class in a controller in charge of the login flow. This view-model is different than the
    /// usual since it has no backing object as model. It behaves similar to a controller in the MVC patterns
    /// but takes adnvantage of the binding model that MVVM depends on. The email and password fields are bounded
    /// to the view and allow automatic validation through IDataErrorInfo interface which expose error on the
    /// view-model properties.
    /// </summary>
    public class LoginViewModel : ILoginViewModel, IDataErrorInfo
    {
        private string email;
        private string password;
        
        private const string EMAIL_PROPERTY_NAME = "Email";
        private const string PASSWORD_PROPERTY_NAME = "Password";
        private const string MANDATORY_FIELD_ERROR_MESSAGE = "This field is mandatory";

        private readonly Dictionary<string, string> errors;
        public event PropertyChangedEventHandler PropertyChanged = (sender, args) => { };

        public LoginViewModel()
        {
            errors = new Dictionary<string, string>();
            LoginCommand = new LoginCommand(this);
            UpdateEmailError();
            UpdatePasswordError();
        }

        private void UpdateEmailError()
        {
            errors[EMAIL_PROPERTY_NAME] = CheckForMandatoryError(email);
        }

        private static string CheckForMandatoryError(string value)
        {
            return string.IsNullOrEmpty(value) ? MANDATORY_FIELD_ERROR_MESSAGE : null;
        }

        private void UpdatePasswordError()
        {
            errors[PASSWORD_PROPERTY_NAME] = CheckForMandatoryError(password);
        }

        public string this[string columnName]
        {
            get
            {
                return errors[columnName];
            }
        }

        public string Error
        {
            get { throw new NotImplementedException(); }
        }

        public string Email
        {
            get
            {
                return email;
            }
            set
            {
                email = value;
                UpdateEmailError();
                PropertyChanged(this, new PropertyChangedEventArgs("Email"));
            }
        }

        public string Password
        {
            get
            {
                return password;
            }
            set
            {
                password = value;
                UpdatePasswordError();
                PropertyChanged(this, new PropertyChangedEventArgs("Password"));
            }
        }

        public ICommand LoginCommand { get; private set; }
        
        public void LoginFailed()
        {
            MessageBox.Show("Login failed");
        }
    }
}